﻿using System;
using protobuf.Error;
using protobuf.Protocol;
using UnityEngine;
using Tools;

namespace Core.Net
{
    public interface IRPCAsyncResultHandler
    {
        /// <summary>
        /// 设置超时时长
        /// </summary>
        /// <param name="time"></param>
        void SetTimeOut(float time);
    }

    /// <summary>
    /// RPC请求结果
    /// </summary>
    public class RPCAsyncResult : CustomYieldInstruction
    {

        #region Yield处理 
        public override bool keepWaiting => !isCompleted;

        #endregion

        /// <summary>
        /// 返回参数
        /// </summary>
        internal object resultParam0 = null;
        internal object resultParam1 = null;

        /// <summary>
        /// 回调请求的参数
        /// </summary>
        internal ByteBuf param = null;
        internal bool isCompleted = false;
        internal Delegate callBack;

        /// <summary>
        /// 对应RPC请求的消息ID
        /// </summary>
        internal int MSGID;

        /// <summary>
        /// 对应RPC请求的RPCID
        /// </summary>
        internal ProtoType RPCID;
        
        internal ProtolcalType protoType = ProtolcalType.Ahead;

        //对应RPC请求的数据帧
        internal Frame frame;

        //是否超时
        internal bool isTimeOut = false;

        // 计时器ID，用于停止计时器
        internal uint timerID = 0;

        internal RPCErrorType errorType = RPCErrorType.None;

        internal long sendTime;

        internal long receiveTime;

        /// <summary>
        /// 当完成后的回调,不带自己为回传参数
        /// </summary>
        public readonly Signal OnFinishedOnly = new Signal();
        
        /// <summary>
        /// 当完成后的回调,带自己为回传参数，提高API简便
        /// </summary>
        public readonly Signal<RPCAsyncResult> OnFinished = new Signal<RPCAsyncResult>();
  
        internal RPCAsyncResult()
        {
        }

        internal RPCAsyncResult(Delegate callBack)
        {
            this.callBack = callBack;
        }

        internal void Finish()
        {
            OnFinishedOnly.Dispatch();
            OnFinished.Dispatch(this);
        }
         
        #region Public Member 

        public bool IsError => errorType != RPCErrorType.None;

        /// <summary>
        /// ACK错误数据原始信息
        /// </summary>
        internal ErrorModel errorData;

        #endregion
    }
}
